﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Content;

namespace DARE
{
    public class CSequence
    {
        #region fields

        private Dictionary<float, List<CTimedItem>> m_timersStart = new Dictionary<float,List<CTimedItem>>();
        private List<CTimedItem> m_activeTimers = new List<CTimedItem>();
        private float m_time;
        private float m_lastTime;
        private bool m_isStarted;

        #endregion

        #region methods

        public CSequence AddTimedItem(float startTime, CTimedItem item)
        {
            if (!m_timersStart.ContainsKey(startTime))
                m_timersStart.Add(startTime, new List<CTimedItem>());
            m_timersStart[startTime].Add(item);
            return this;
        }

        public CSequence DropTimedItem(CTimedItem item)
        {
            for (int i = 0; i < m_timersStart.Count; ++i)
            {
                CTimedItem it = (from el in m_timersStart.ElementAt(i).Value where el == item select el).FirstOrDefault();
                if (it != null)
                {
                    m_timersStart.ElementAt(i).Value.Remove(it);
                    return this;
                }
            }
            return this;
        }

        public CSequence DropAllAt(float startTime)
        {
            m_timersStart.Remove(startTime);
            return this;
        }

        public CSequence Clear()
        {
            m_timersStart.Clear();
            return this;
        }

        public void Initialize()
        {
            m_isStarted = false;
        }

        public void Update(float elapsedTime)
        {
            if (m_isStarted)
            {
                m_lastTime = m_time;
                m_time += DARE.CDare.Instance.Config.Time.TimeSinceLastFrame;
                foreach (List<CTimedItem> itemList in (from el in m_timersStart where el.Key > m_lastTime && el.Key <= m_time orderby el.Key ascending select el.Value))
                    foreach (CTimedItem item in itemList)
                    {
                        item.Start(m_time);
                        m_activeTimers.Add(item);
                    }
            }
            for (int i = 0; i < m_activeTimers.Count; ++i)
            {
                CTimedItem item = m_activeTimers.ElementAt(i);
                if (item.Duration < m_time - item.StartTime)
                {
                    item.Finish(item.StartTime, m_time, DARE.CDare.Instance.Config.Time.TimeSinceLastFrame);
                    m_activeTimers.Remove(item);
                    --i;
                }
                else
                    item.Update(item.StartTime, m_time, DARE.CDare.Instance.Config.Time.TimeSinceLastFrame);
            }
        }

        public void Start()
        {
            m_isStarted = true;
            m_time = 0;
        }

        public void Pause()
        {
            m_isStarted = !m_isStarted;
        }

        public void Stop()
        {
            m_isStarted = false;
            m_time = 0;
        }

        public void Restart()
        {
            m_time = 0;
        }

        #endregion
    }
    
}
